import 'dart:developer';

import 'package:dio/dio.dart';
import 'package:my_desk_flutter/api/wan_api.dart';
import 'package:my_desk_flutter/model/person_info.dart';
import 'package:my_desk_flutter/net/dio_client.dart';
import 'package:my_desk_flutter/storage/storage_service_provider.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'auth_controller.g.dart';

sealed class Auth {
  const factory Auth.signedIn({
    required int id,
    required String displayName,
    required String email,
    required String icon,
  }) = SignedIn;

  const Auth._();

  factory Auth.signedOut() = SignedOut;

  bool get isAuth => switch (this) {
        SignedIn() => true,
        SignedOut() => false,
      };
}

class SignedOut extends Auth {
  const SignedOut() : super._();
}

class SignedIn extends Auth {
  final int id;
  final String displayName;
  final String email;
  final String icon;

  const SignedIn({
    required this.id,
    required this.displayName,
    required this.email,
    required this.icon,
  }) : super._();
}

@riverpod
Map<String, dynamic>? authProvider(AuthProviderRef ref) {
  final data =
      ref.read(storageServiceProvider).get('token') as Map<dynamic, dynamic>?;
  return data
      ?.map((key, value) => MapEntry(key.toString(), value))
      .cast<String, dynamic>();
}

@riverpod
class AuthController extends _$AuthController {
  late final api = ref.watch(wanApiProvider);

  void refreshCurrent() {
    ref.invalidateSelf();
  }

  @override
  Future<Auth> build() async {
    final saveData = ref.refresh(authProviderProvider);
    if (saveData != null) {
      return SignedIn(
        id: saveData['id'],
        displayName: saveData['nickname'].toString(),
        email: saveData['email'].toString(),
        icon: saveData['icon'].toString(),
      );
    }
    return Auth.signedOut();
  }

  Future login(String name, String password) async {
    state = const AsyncLoading();
    // 模拟请求
    final result = await api.login(username: name, password: password);
    if (result.data['errorCode'] == 0) {
      await ref.read(storageServiceProvider).set('token', result.data['data']);
      ref.invalidateSelf();
    } else {
      state = AsyncData(Auth.signedOut());
    }
  }

  Future logout() async {
    state = const AsyncLoading();
    await api.logout();
    await ref.read(storageServiceProvider).set('token', null);
    ref.invalidateSelf();
  }

  //登录态无效时，清理状态
  Future resetLogout() async {
    if (state.value?.isAuth ?? false) {
      ref.read(storageServiceProvider).set('token', null);
      ref.invalidateSelf();
    }
  }
}
